package br.com.mtg.movethegarbage.impl;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;

import android.content.Context;
import br.com.mtg.movethegarbage.framework.FileIO;

public class GameFileIO extends FileIO
{

	public GameFileIO(Context _context)
	{
		super(_context);
	}

	@Override
	public InputStream readAsset(String fileName) throws Exception
	{
		return assetManager.open(fileName);
	}

	@Override
	public InputStream readFile(String fileName) throws Exception
	{
		return context.openFileInput(fileName);
	}

	@Override
	public OutputStream writeFile(String fileName, boolean append) throws Exception
	{
		return context.openFileOutput(fileName, (append == true ? Context.MODE_APPEND | Context.MODE_PRIVATE : Context.MODE_PRIVATE));
	}

	@Override
	public boolean checkIfExists(String fileName) throws Exception
	{
		return context.getFileStreamPath(fileName).exists();
	}

	@Override
	public String[] listFiles() throws Exception
	{
		return context.fileList();
	}

	public ArrayList<String> readAndFragment(String fileName, int size) throws Exception
	{
		File willBeRead = new File(fileName);
		int FILE_SIZE = (int) willBeRead.length();
		ArrayList<String> nameList = new ArrayList<String>();

		int NUMBER_OF_CHUNKS = 0;
		byte[] temporary = null;

		try
		{
			InputStream inStream = null;
			int totalBytesRead = 0;

			try
			{
				inStream = new BufferedInputStream(new FileInputStream(willBeRead));

				while (totalBytesRead < FILE_SIZE)
				{
					String PART_NAME = "data" + NUMBER_OF_CHUNKS + ".bin";
					int bytesRemaining = FILE_SIZE - totalBytesRead;
					if (bytesRemaining < size)
					{
						size = bytesRemaining;
					}
					temporary = new byte[size];
					int bytesRead = inStream.read(temporary, 0, size);

					if (bytesRead > 0)
					{
						totalBytesRead += bytesRead;
						NUMBER_OF_CHUNKS++;
					}

					writeFile(PART_NAME, false).write(temporary);
					nameList.add(PART_NAME);
				}

			}
			finally
			{
				inStream.close();
			}
		}
		catch (Exception e)
		{
			throw e;
		}
		return nameList;
	}

	public ByteBuffer mergeParts(ArrayList<String> nameList) throws Exception
	{
		InputStream[] file = new InputStream[nameList.size()];
		byte AllFilesContent[] = null;

		int TOTAL_SIZE = 0;
		int FILE_NUMBER = nameList.size();
		int FILE_LENGTH = 0;
		int CURRENT_LENGTH = 0;

		for (int i = 0; i < FILE_NUMBER; i++)
		{
			file[i] = this.readAsset(nameList.get(i));
			TOTAL_SIZE += file[i].available();
		}

		try
		{
			AllFilesContent = new byte[TOTAL_SIZE];
			InputStream inStream = null;

			for (int j = 0; j < FILE_NUMBER; j++)
			{
				inStream = new BufferedInputStream(file[j]);
				FILE_LENGTH = (int) inStream.available();
				inStream.read(AllFilesContent, CURRENT_LENGTH, FILE_LENGTH);
				CURRENT_LENGTH += FILE_LENGTH;
				inStream.close();
			}

		}
		catch (Exception e)
		{
			throw e;
		}
		
		return ByteBuffer.wrap(AllFilesContent);
	}

}
